lxml介绍

Python的lxml 模组是一个非常好用且效能高的HTML、XML解析工具,通过它解析网页,爬虫就可以轻松的从网页中提取想要的资料。 lxml对XML和HTML都有很好的支援,分别使用 lxml.etree 和 lxml.html 两个模组。

使用lxml提取网页资料的流程

要从网页里面提取资料,使用lxml需要两步:

  • 第一步,用lxml把网页(或xml)解析成一个DOM树。这个过程,我们可以选择etreeetree.HTMLlxml.html这三种来实现,它们基本类似但又有些许差别。
  • 第二步,使用xpath遍历这棵DOM 树,找到你想要的资料所在的节点并提取。这一步要求我们对xpath规则比较熟练,xpath规则很多,但别怕,我来总结一些常用的套路。

生成DOM树

上面我们说了,可以有三种方法来把网页解析成DOM树,那么我们选择哪一种呢?

一般HTML网页用这个比较多:etree.HTML(html)lxml.html(html)

🌟etree.HTML(html)

我们可以用这个:print(etree.tostring(etree.HTML(html)).decode())来将dom树还原成之前的html,我们可以发现etree.HTML()函式会补全html程式码片段,给它们加上<html><body>标签。

🌟lxml.html(html)

lxml.html是lxml的子模组,它是对etree的封装,更适合解析html网页。生成DOM树的方法有多个:

  • lxml.html.document_fromstring()
  • lxml.html.fragment_fromstring()
  • lxml.html.fragments_fromstring()
  • lxml.html.fromstring()

我们解析网页用最后一个fromstring()即可。

使用xpath提取资料

以下面一段简单的html为例,来介绍一下xpath对资料的提取:

1
2
3
4
5
6
7
<div class="1">
<p class="p_1 item">item_1</p>
<p class="p_2 item">item_2</p>
</div>
<div class="2">
<p id="p3"><a href="/go-p3">item_3</a></p>
</div>
  1. 首先生成DOM树:
1
2
from lxml import etree 
doc = etree.HTML(html)
  1. 通过标签属性定位节点:比如我们要获取<div class="2">这节点:
1
2
3
4
5
doc.xpath('//div[@class="2"]')
print(etree.tostring(doc.xpath('//div[@class="2"]')[0]).decode())
# <div class="2">
# <p id="p3"><a href="/go-p3">item_3</a></p>
# </div>
  1. contains语法

html中有两个<p>标签的class含有item,如果我们要提取这两个<p>标签,则:

1
2
3
4
## 获取<p>的文字:
doc.xpath('//p[contains(@class, "item")]/text()')

# >> ['item_1', 'item_2']
  1. starts-with语法

一样的提取需求,两个<p>标签的class都是以p_开头的,所以:

1
2
3
4
## 获取<p>的文字:
doc.xpath('//p[starts-with(@class, "p_")]/text()')

# >> ['item_1', 'item_2']
  1. 获取某一属性的值

比如,我们想提取网页中所有的连结:

1
2

doc.xpath('//@href')